//
//  NSTableViewExtension.swift
//  JKTools
//
//  Created by 姜奎 on 2/25/25.
//

import Cocoa

extension NSTableView {

    func setBackgroundColor(_ color: NSColor) {

        backgroundColor = color
        enclosingScrollView?.backgroundColor = color

        if let clipView = enclosingScrollView?.documentView as? NSClipView {
            clipView.backgroundColor = color
        }
    }

    func isRowSelected(_ row: Int) -> Bool {
        selectedRowIndexes.contains(row)
    }

    func selectRow(_ row: Int) {
        selectRowIndexes(IndexSet(integer: row), byExtendingSelection: false)
    }

    func selectRows(_ rows: [Int]) {
        selectRowIndexes(IndexSet(rows), byExtendingSelection: false)
    }

    func selectRows(_ rows: IndexSet) {
        selectRowIndexes(rows, byExtendingSelection: false)
    }

    func redoRowSelection() {

            // Note down the selected rows, clear the selection, and re-select the originally selected rows
            // (to trigger a repaint of the selection boxes).

        let selRows = selectedRowIndexes

        if !selRows.isEmpty {

            selectRowIndexes(IndexSet([]), byExtendingSelection: false)
            selectRowIndexes(selRows, byExtendingSelection: false)
        }
    }

    func selectRows(_ rows: Range<Int>) {
        selectRowIndexes(IndexSet(rows), byExtendingSelection: false)
    }

    func selectRows(_ rows: ClosedRange<Int>) {
        selectRowIndexes(IndexSet(rows), byExtendingSelection: false)
    }

    func selectAllItems() {
        selectRowIndexes(allRowIndices, byExtendingSelection: false)
    }

    func clearSelection() {
        selectRowIndexes(IndexSet([]), byExtendingSelection: false)
    }

    func invertSelection() {
        selectRowIndexes(invertedSelection, byExtendingSelection: false)
    }

    var invertedSelection: IndexSet {
        IndexSet((0..<numberOfRows).filter {!selectedRowIndexes.contains($0)})
    }

    var allRowIndices: IndexSet {IndexSet(0..<numberOfRows)}

    var allColumnIndices: IndexSet {IndexSet(0..<numberOfColumns)}

    func reloadRows(_ rows: [Int]) {
        reloadData(forRowIndexes: IndexSet(rows), columnIndexes: allColumnIndices)
    }

    func reloadRows(_ rows: Range<Int>) {
        reloadData(forRowIndexes: IndexSet(rows), columnIndexes: allColumnIndices)
    }

    func reloadRows(_ rows: ClosedRange<Int>) {
        reloadData(forRowIndexes: IndexSet(rows), columnIndexes: allColumnIndices)
    }

    func reloadRows(_ rows: ClosedRange<Int>, columns: [Int]) {
        reloadData(forRowIndexes: IndexSet(rows), columnIndexes: IndexSet(columns))
    }

    func reloadRows(_ rows: IndexSet) {
        reloadData(forRowIndexes: rows, columnIndexes: allColumnIndices)
    }

    func reloadRows(_ rows: [Int], columns: [Int]) {
        reloadData(forRowIndexes: IndexSet(rows), columnIndexes: IndexSet(columns))
    }

    func reloadRows(_ rows: IndexSet, columns: [Int]) {
        reloadData(forRowIndexes: rows, columnIndexes: IndexSet(columns))
    }

    func reloadAllRows(columns: [Int]) {
        reloadData(forRowIndexes: allRowIndices, columnIndexes: IndexSet(columns))
    }

    func reloadDataMaintainingSelection() {

        let selectedRows = selectedRowIndexes
        reloadData()
        selectRowIndexes(selectedRows, byExtendingSelection: false)
    }

    func pageUp() {
        enclosingScrollView?.pageUp(self)
    }

    var heightOfARow: CGFloat {self.rect(ofRow: 0).height}

    func pageDown() {
        enclosingScrollView?.pageDown(self)
    }

        // Scrolls the playlist view to the very top
    func scrollToTop() {

        if numberOfRows > 0 {
            scrollRowToVisible(0)
        }
    }

        // Scrolls the playlist view to the very bottom
    func scrollToBottom() {

        if numberOfRows > 0 {
            scrollRowToVisible(numberOfRows - 1)
        }
    }
}
